#ifndef PRIMITIVE_H
#define PRIMITIVE_H

#include "geometry.h"
#include "shape.h"
#include "material.h"

// Primitive Declarations
class Primitive {
public:
    // Primitive Interface
    Primitive() : primitiveId(nextprimitiveId++) { }
    virtual ~Primitive();

    virtual BBox WorldBound() const = 0;
    virtual bool CanIntersect() const;
    virtual bool Intersect(const Ray &r, Intersection *in) const = 0;
    virtual bool IntersectP(const Ray &r) const = 0;

    virtual Material* getMaterial() const = 0;
    // Primitive Public Data
    const uint32_t primitiveId;
protected:
    // Primitive Protected Data
    static uint32_t nextprimitiveId;
};


// GeometricPrimitive Declarations
class GeometricPrimitive : public Primitive {
public:
    // GeometricPrimitive Public Methods
    bool CanIntersect() const;
    virtual BBox WorldBound() const;
    virtual bool Intersect(const Ray &r, Intersection *isect) const;
    virtual bool IntersectP(const Ray &r) const;
    virtual Material* getMaterial() const;

    GeometricPrimitive( Shape *s, Material *m);

private:
    // GeometricPrimitive Private Data
    Shape *shape;
    Material *material;
};


// Aggregate Declarations
class Aggregate : public Primitive {
public:    
    virtual Material* getMaterial() const {
        Error("Aggregate: getMaterial called");
    }

private:
    int tmp;
};



#endif // PRIMITIVE_H
